ActiveAdmin.register Block do

  permit_params :ts_code, :name, :count, :cate_type, :is_choice, :cycle

  scope :is_choice?, :default => true
  scope :all

  index do
    selectable_column
    id_column
    column :ts_code
    column :name
    column :count
    column :cate_type
    column :is_choice
    column :updated_at
    actions
  end

  filter :cate_type
  filter :name
  filter :ts_code
  filter :is_choice

  form do |f|
    f.inputs do
      f.input :name
      f.input :is_choice
      f.input :cycle
    end
    f.actions
  end

  show do
    trade_date_cycle = trade_date(resource.cycle || 10) # 获取(resource.cycle || 10)个交易日前的日期
    stocks = $TusharePro.tushare_pro("ths_member", "ts_code": resource.ts_code).select { |x| x["con_code"][0..5] < "680000" && x["con_code"][0] != "4" }

    all_codes = stocks.pluck("con_code").map { |x| x[0..5] }
    all_codes_pool = stocks.pluck("con_code").map { |x| x[0..5] }
    all_codes.each do |batch|
      next if all_codes_pool.exclude? batch

      codes = all_codes_pool[0..58] # 调整每次获取数量
      flows = RealTime.fc_ths_flow(codes.join("-"))
      puts Time.now
      flows_arr = Array[codes.zip(flows["results"])]

      arr = []
      flows_arr.first.each do |symbol, flow|
        if flow.nil?
          debugger
        end
        stock = Stock.find_by_symbol(symbol)
        stock.update(ths_flow: flow["title"]["je"]) unless stock.nil?
        arr << symbol
        next if flow["field"].blank?
        flow["field"]["hyzdf"].each do |ths_flow|
          next if Stock.find_by_symbol(ths_flow["stockcode"]).nil?
          Stock.find_by_symbol(ths_flow["stockcode"]).update(ths_flow: ths_flow["je"])
          arr << ths_flow["stockcode"].to_s
        end
        (flow["field"]["desc"] + flow["field"]["asc"]).each do |ths_flow|
          next if Stock.find_by_symbol(ths_flow["stockcode"]).nil?
          Stock.find_by_symbol(ths_flow["stockcode"]).update(ths_flow: ths_flow["ddje"])
          arr << ths_flow["stockcode"].to_s
        end
        all_codes_pool = all_codes_pool - arr
      end
    end
    puts "数据准备完成"
    attributes_table do
      row :name
      row :count
      row 'rake' do |block|
        "rake ths:block_stock['#{resource.ts_code}']"
      end
      panel "当日板块流入趋势" do
        BlockFlow.last.created_at
        block_flows = BlockFlow.where(name: resource.name, created_at: BlockFlow.last.created_at.beginning_of_day..BlockFlow.last.created_at.end_of_day, cate_type: resource.cate_type)
        created_ats = block_flows.pluck(:created_at).map { |x| x.strftime("%H:%M") }
        net_amounts = block_flows.pluck(:net_amount)
        div id: "main", style: "width: 80%; height: 300px;"
        script <<~JS.html_safe
          var chartDom = document.getElementById('main');
          var myChart = echarts.init(chartDom);
          var option;

          option = {
            xAxis: {
              type: 'category',
              data: #{raw created_ats}
            },
            yAxis: {
              type: 'value'
            },
            series: [
              {
                data: #{raw net_amounts},
                type: 'line'
              }
            ]
          };
          // 响应式调整
          option && myChart.setOption(option);
        JS
      end


      panel "近期板块流入趋势" do
        # 进 trade_date_cycle || 10 日板块资金流入情况
        if  resource.cate_type == "N"
          moneyflow_ths = $TusharePro.tushare_pro("moneyflow_cnt_ths", ts_code: resource.ts_code, "start_date": trade_date_cycle, "end_date": Time.now.strftime("%Y%m%d"))
        else
          moneyflow_ths = $TusharePro.tushare_pro("moneyflow_ind_ths", ts_code: resource.ts_code, "start_date": trade_date_cycle, "end_date": Time.now.strftime("%Y%m%d"))
        end
        created_ats = moneyflow_ths.map { |x| "#{x['trade_date'][0..3]}-#{x['trade_date'][4..5]}-#{x['trade_date'][6..7]}" }.reverse
        net_amounts = moneyflow_ths.map { |x| x["net_amount"].to_f.round(2) }.reverse
        net_amounts = net_amounts.each_with_index.map { |x, i| net_amounts[0..i].sum }

        div id: "block_cycle_flow", style: "width: 80%; height: 300px;"
        script <<~JS.html_safe
          var block_cycle_flow_Dom = document.getElementById('block_cycle_flow');
          var block_cycle_flow_Chart = echarts.init(block_cycle_flow_Dom);

          block_cycle_flow_option = {
            xAxis: {
              type: 'category',
              data: #{raw created_ats}
            },
            yAxis: {
              type: 'value'
            },
            series: [
              {
                data: #{raw net_amounts},
                type: 'line'
              }
            ]
          };
          // 响应式调整
          block_cycle_flow_option && block_cycle_flow_Chart.setOption(block_cycle_flow_option);
        JS
      end
      puts "flow_chart 图表渲染完成"
      panel " changepercent > 8 " do
        table_for resource.stocks.select { |x| (JSON.parse $Redis.get(x.symbol))["changepercent"]&.to_f > 8 } do
          column :name do |stock|
            link_to "#{stock.name}", "https://stockpage.10jqka.com.cn/#{stock.ts_code[0..5]}/", target: '_blank', rel: "noopener noreferrer"
          end
          column :ts_code do |stock|
            link_to "#{stock.symbol}", admin_stock_path(stock.id)
          end
          column :per do |stock|
            "#{(JSON.parse $Redis.get(stock.symbol))["per"]}" unless $Redis.get(stock.symbol).nil?
          end
          column :mktcap do |stock|
            "#{((JSON.parse $Redis.get(stock.symbol))["mktcap"]&.to_f / 10000).round(0)}" unless $Redis.get(stock.symbol).nil?
          end
          column :nmc do |stock|
            "#{((JSON.parse $Redis.get(stock.symbol))["nmc"]&.to_f / 10000).round(0)}" unless $Redis.get(stock.symbol).nil?
          end
          column :change do |stock|
            "#{(JSON.parse $Redis.get(stock.symbol))["changepercent"]&.to_f.round(2)}%" unless $Redis.get(stock.symbol).nil?
          end
          column :ths_flow
          column :year_count
          column :volume_change do |stock|
            today_volume stock.symbol
          end
          column :is_buy_point
          column :is_choice
        end
      end

      stock_klines = Parallel.map(block.stocks, in_processes: 8, progress: true) do |stock|
        kline = Tushare::Stock::Trading.get_k_data(stock.symbol, "#{trade_date_cycle[0..3]}-#{trade_date_cycle[4..5]}-#{trade_date_cycle[6..7]}", Time.now.strftime("%Y-%m-%d"))
        next if kline.empty?
        # k_line_10 = kline.last resource.cycle
        # puts "#{stock.name} -- #{stock.symbol} -- #{k_line_10.first["close"]} -- #{k_line_10.last["close"]} -- #{k_line_10.first["date"]} -- #{k_line_10.last["date"]}"
        # puts "#{stock.name} -- #{stock.symbol} -- #{kline.pluck("low").min} -- #{kline.pluck("high").max} -- #{kline.first["date"]} -- #{kline.last["date"]}"
        { name: stock.name, symbol: stock.symbol, change_10: cul_change(kline.first["close"], kline.last["close"]), ths_flow: stock.ths_flow, year_count: stock.year_count, is_buy_point: stock.is_buy_point, is_choice: stock.is_choice, amplitude: cul_change(kline.pluck("low").min, kline.pluck("high").max) }
      end
      change_top10 = stock_klines.compact.sort_by { |x| x[:change_10] }.reverse.first(10)
      amplitude_top10 = stock_klines.compact.sort_by { |x| x[:amplitude] }.reverse.first(10)
      puts "change_top10 amplitude_top10 数据准备完成"
      panel " #{resource.cycle || 10}日涨幅排名前10 " do
        table_for change_top10 do
          column :name
          column :symbol
          column :change_10
          column :amplitude
          column :mktcap do |stock|
            "#{((JSON.parse $Redis.get(stock[:symbol]))["mktcap"]&.to_f / 10000).round(0)}" unless $Redis.get(stock[:symbol]).nil?
          end
          column :nmc do |stock|
            "#{((JSON.parse $Redis.get(stock[:symbol]))["nmc"]&.to_f / 10000).round(0)}" unless $Redis.get(stock[:symbol]).nil?
          end
          column :change do |stock|
            "#{(JSON.parse $Redis.get(stock[:symbol]))["changepercent"]&.to_f.round(2)}%" unless $Redis.get(stock[:symbol]).nil?
          end
          column :ths_flow
          column :year_count
          # column :volume_change do |stock|
          #   today_volume stock[:symbol]
          # end
          # column :score do |stock|
          #   RealTime.hs_ths_flow(stock[:symbol])["score"]
          # end
          column :is_buy_point
          column :is_choice
        end
      end

      panel " #{resource.cycle || 10}日振幅排名前10 " do
        table_for amplitude_top10 do
          column :name
          column :symbol
          column :change_10
          column :amplitude
          column :mktcap do |stock|
            "#{((JSON.parse $Redis.get(stock[:symbol]))["mktcap"]&.to_f / 10000).round(0)}" unless $Redis.get(stock[:symbol]).nil?
          end
          column :nmc do |stock|
            "#{((JSON.parse $Redis.get(stock[:symbol]))["nmc"]&.to_f / 10000).round(0)}" unless $Redis.get(stock[:symbol]).nil?
          end
          column :change do |stock|
            "#{(JSON.parse $Redis.get(stock[:symbol]))["changepercent"]&.to_f.round(2)}%" unless $Redis.get(stock[:symbol]).nil?
          end
          column :ths_flow
          column :year_count
          # column :volume_change do |stock|
          #   today_volume stock[:symbol]
          # end
          # column :score do |stock|
          #   RealTime.hs_ths_flow(stock[:symbol])["score"]
          # end
          column :is_buy_point
          column :is_choice
        end
      end

      panel "股票列表 ths_flow > 0 year_count > 0 changepercent < 5 sort_by-->ths_flow first(25)" do
        table_for resource.stocks.select { |x| x.ths_flow.to_f > 0 && x.year_count.to_i > 0 && (JSON.parse $Redis.get(x.symbol))["changepercent"]&.to_f < 5 }.sort_by { |x| x.ths_flow }.reverse.first(25) do
          column :name do |stock|
            link_to "#{stock.name}", "https://stockpage.10jqka.com.cn/#{stock.ts_code[0..5]}/", target: '_blank', rel: "noopener noreferrer"
          end
          column :ts_code do |stock|
            link_to "#{stock.symbol}", admin_stock_path(stock.id)
          end
          column :per do |stock|
            "#{(JSON.parse $Redis.get(stock.symbol))["per"]}" unless $Redis.get(stock.symbol).nil?
          end
          column :change do |stock|
            "#{(JSON.parse $Redis.get(stock.symbol))["changepercent"]&.to_f.round(2)}%" unless $Redis.get(stock.symbol).nil?
          end
          column :ths_flow do |stock|
            link_to "#{stock.ths_flow}", "https://stockpage.10jqka.com.cn/#{stock.symbol}/funds/#funds_sszjlx", target: '_blank', rel: "noopener noreferrer"
          end
          column :year_count
          column :volume_change do |stock|
            today_volume stock.symbol
          end
          column :score do |stock|
            RealTime.ths_flow(stock.symbol)["score"]
          end
          column :is_buy_point
          column :is_choice
          column :edit do |stock|
            link_to "编辑", edit_admin_stock_path(stock.id), class: "button", target: '_blank', rel: "noopener noreferrer"
          end
        end
      end
      panel "股票列表" do
        table_for resource.stocks.sort_by { |x| (x&.ths_flow || 0).to_f }.reverse do
          column :name do |stock|
            link_to "#{stock.name}", "https://stockpage.10jqka.com.cn/#{stock.ts_code[0..5]}/", target: '_blank', rel: "noopener noreferrer"
          end
          column :ts_code do |stock|
            link_to "#{stock.symbol}", admin_stock_path(stock.id)
          end
          column :per do |stock|
            "#{(JSON.parse $Redis.get(stock.symbol))["per"]}" unless $Redis.get(stock.symbol).nil?
          end
          column :mktcap do |stock|
            "#{((JSON.parse $Redis.get(stock[:symbol]))["mktcap"]&.to_f / 10000).round(0)}" unless $Redis.get(stock[:symbol]).nil?
          end
          column :nmc do |stock|
            "#{((JSON.parse $Redis.get(stock[:symbol]))["nmc"]&.to_f / 10000).round(0)}" unless $Redis.get(stock[:symbol]).nil?
          end
          column :change do |stock|
            "#{(JSON.parse $Redis.get(stock.symbol))["changepercent"]&.to_f.round(2)}%" unless $Redis.get(stock.symbol).nil?
          end
          column :ths_flow
          column :year_count
          column :score
          column :is_buy_point
          column :is_choice
          column :blockoooooooooooooooooooooooooooooooooooooooooooooooooooooo do |stock|
            div do
              gn_bases = BlockFlow.where(cate_type: "N", mark: "base").last(50)
              hy_bases = BlockFlow.where(cate_type: "I", mark: "base").last(50)
              stock.blocks.pluck(:name).each do |sk|
                if (gn_bases + hy_bases).pluck(:name).include?(sk)
                  span link_to "#{sk}", admin_block_path(Block.find_by_name(sk).id), style: "background-color: #ffcccc;", target: '_blank', rel: "noopener noreferrer"
                else
                  span link_to "#{sk}", admin_block_path(Block.find_by_name(sk).id), style: "background-color: #bbe5f0;", target: '_blank', rel: "noopener noreferrer"
                end
              end
            end

          end

          column :edit do |stock|
            link_to "编辑", edit_admin_stock_path(stock.id), class: "button", target: '_blank', rel: "noopener noreferrer"
          end
        end
      end

      4.times do |time|
        columns do
          (1..5).each do |i|
            date = trade_date(time * 5 + i)
            day_of_week = Date.parse("#{date[0..3]}-#{date[4..5]}-#{date[6..7]}").wday
            column do
              dailies = $TusharePro.tushare_pro("daily", "trade_date": date).select { |daily| stocks.pluck("con_code").include? daily["ts_code"] }
              stks = dailies.sort_by { |x| x["pct_chg"].to_f }.map{|x| x.transform_keys(&:to_sym)}.reverse
              panel "#{date}  星期#{day_of_week}" do
                table_for stks.first(5) do
                  column :ts_code do |stk|
                    stock = Stock.find_by_ts_code(stk[:ts_code])
                    link_to "#{stock.symbol}", admin_stock_path(stock.id)
                  end
                  column "【name】" do |stock|
                    Stock.find_by_ts_code(stock[:ts_code]).name
                  end
                  column :change do |stock|
                    "#{stock[:pct_chg].round(2)}%"
                  end
                  column :edit do |stock|
                    link_to "编辑", edit_admin_stock_path(Stock.find_by_ts_code(stock[:ts_code]).id), target: '_blank', rel: "noopener noreferrer"
                  end
                end
              end
            end
          end
        end
      end
    end
  end

  config.sort_order = 'created_at_desc'
  config.per_page = 500
  config.batch_actions = false
end

def today_volume(code)
  sse = $TusharePro.tushare_pro("trade_cal", "exchange": "SSE", "start_date": (Time.now - 10.day).strftime("%Y%m%d"), "end_date": (Time.now).strftime("%Y%m%d")).select { |sse| sse["is_open"] == 1 }
  today_trade_date, yesterday_trade_date = sse.first(1).last["cal_date"], sse.first(1).last["pretrade_date"]
  today, yesterday = "#{today_trade_date[0, 4]}-#{today_trade_date[4, 2]}-#{today_trade_date[6, 2]}", "#{yesterday_trade_date[0, 4]}-#{yesterday_trade_date[4, 2]}-#{yesterday_trade_date[6, 2]}"
  delay_millisecond(1, 50) {}
  kline = RealTime.hs_kline to_sina_code(code)
  today_5min = kline.select { |x| x["day"].split(" ")[0] == today }
  yesterday_5min = kline.select { |x| x["day"].split(" ")[0] == yesterday }.first(today_5min.count)
  today_volume = today_5min.pluck("volume").sum { |x| x.to_f }
  yes_volume = yesterday_5min.pluck("volume").sum { |x| x.to_f }
  (today_volume / yes_volume).round(2) if yes_volume != 0
end

def to_sina_code(code)
  return %w(5 6 9).include?(code.to_s[0]) ? "sh#{code}" : "sz#{code}" if code.size == 6
  return code[-2..-1].downcase + code[0..5] if code[6] == "."
  code if code[0..1] == "sh" || code[0..1] == "sz"
end

def cul_change(open, close)
  ((close.to_f - open.to_f) * 100 / open.to_f).round(2)
end